//
//  NTESSocket.m
//  ScreenRecord_ios_oc
//
//  Created by 51talk on 2021/5/21.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "NTESSocket.h"

#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

@interface NTESSocket()
@property int curSocket;

@end


@implementation NTESSocket
int const kMaxConnectCount = 1;

//通过 Socket 方案录制系统屏幕，另外单独配置分辨率
int const frameBufferPacketLen = 2549022; //886*1918*3/2
//1382400;// 720*1280*3/2
int const socketBlockLen = 1024;

-(NTESSocket *)initWithPort:(NSString*)port ip:(NSString*)ip {
    self.curSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    struct sockaddr_in addr;
    addr.sin_len = sizeof(struct sockaddr_in);
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr([ip UTF8String]);
    addr.sin_port = htons([port intValue]);
    
    int bind_result = bind(self.curSocket, (struct sockaddr*)&addr, sizeof(addr));
    if (bind_result == -1) {
        NSLog(@"绑定端口失败");
    }else{
        NSLog(@"绑定端口成功");
    }
    
    return self;
}

-(void)startAcceptClient {
    if (listen(self.curSocket, kMaxConnectCount)==-1) {
        NSLog(@"监听失败");
    }else{
        for (int i = 0; i < kMaxConnectCount; i++) {
            //接受客户端的链接
            [self acceptClientWithServerSocket:self.curSocket];
        }
    }
}

//创建线程接受客户端
-(void)acceptClientWithServerSocket:(int)server_socket{
    struct sockaddr_in client_address;
    socklen_t address_len;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        //创建新的socket
        while (1) {
            int client_socket = accept(server_socket, (struct sockaddr*)&client_address,&address_len );
            if (client_socket == -1) {
                NSLog(@"接受客户端链接失败");
            }else{
                NSString *acceptInfo = [NSString stringWithFormat:@"客户端 in,socket:%d",client_socket];
                NSLog(@"%@", acceptInfo);
                //接受客户端数据
                [self recvFromClinetWithSocket:client_socket];
            }
        }
    });
}

//接受客户端数据
- (void)recvFromClinetWithSocket:(int)client_socket{
    int len = 0;
    int offset = 0;
    uint8_t *frameBuffer = nil;
    bool flag = true;
    while (1) {
        //接受客户端传来的数据
        uint8_t buf[socketBlockLen] = {0};
        long iReturn = recv(client_socket, buf, socketBlockLen, 0);

        if (iReturn>0) {
#if 1
            len += iReturn;
            if(len > offset && flag) {
                if(frameBuffer == nil) {
                    frameBuffer = (uint8_t*)malloc(len);
                } else {
                    frameBuffer = (uint8_t*)realloc(frameBuffer, len);
                }
                
                if(frameBuffer == nil) {
                    NSLog(@"no memory");
                }
            }
            
            if(_delegate != nil && len >= frameBufferPacketLen) {
                int remain = frameBufferPacketLen - offset;
                memcpy(frameBuffer+offset, buf, remain);
                [_delegate onRecvData:frameBuffer len:frameBufferPacketLen];
                memset(frameBuffer, 0, frameBufferPacketLen);
                memcpy(frameBuffer, buf+remain, socketBlockLen-remain);
                offset = socketBlockLen-remain;
                len = socketBlockLen-remain;
                flag = false;
            } else {
                memcpy(frameBuffer+offset, buf, iReturn);
                offset+=iReturn;
            }
#endif
        }else if (iReturn == -1){
            NSLog(@"读取消息失败");
            close(client_socket);
            break;
        }else if (iReturn == 0){
            NSLog(@"客户端走了");
            close(client_socket);
            break;
        }
    }
    
    if(frameBuffer != nil) {
        free(frameBuffer);
        frameBuffer = nil;
    }
}

-(bool) connectToServerWithPort:(NSString*)port ip:(NSString*)ip {
    struct sockaddr_in server_addr;
    server_addr.sin_len = sizeof(struct sockaddr_in);
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr([ip UTF8String]);
    server_addr.sin_port = htons([port intValue]);
    
    int aResult = connect(self.curSocket, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_in));
    if (aResult == -1) {
        NSLog(@"连接失败");
        return false;
    }else{
        NSLog(@"连接成功");
        return true;
    }
}

-(void)sendData:(uint8_t*)data length:(int)length {
//    NSLog(@"sendData:length=%d", length);
    send(self.curSocket, data, length, 0);
}

-(void)setDelegate:(id<SocketRecieve>)delegate
{
    _delegate = delegate;
}

-(void)closeSocket {
    close(self.curSocket);
}

@end
